MEMORY
{
    FLASH (rx) : ORIGIN = {{addr config.memory.flash.origin}}, LENGTH = {{size config.memory.flash.size}}
    RAM (wx) : ORIGIN = {{addr config.memory.ram.origin}}, LENGTH = {{size config.memory.ram.size}}
{{~ #each config.memory}}{{#if (and (ne @key "flash") (ne @key "ram"))}}
    {{upcase @key}} (wx) : ORIGIN = {{addr this.origin}}, LENGTH = {{size this.size}}
{{~ /if}}{{/each}}
}

ENTRY(reset);

SECTIONS
{
{{~ #unless stage_two}}
    STACK_POINTER = ORIGIN(RAM);
{{~ else}}
    STACK_POINTER = ORIGIN(RAM) + LENGTH(RAM)
        - _data_section_size
        - _bss_section_size
        - _dronereg_section_size
        - _heap_section_size;
{{~ /unless}}
{{~ #if (eq config.linker.platform "arm") }}

    .vtable ORIGIN(FLASH) :
    {
        LONG(STACK_POINTER);
        KEEP(*(.rodata.VTABLE));
        . = ALIGN(4);
    } > FLASH
{{~ /if}}

    .text :
    {
        *(.text.reset);
        *(.text.*);
        . = ALIGN(4);
    } > FLASH

    .rodata :
    {
        *(.rodata.*);
        . = ALIGN(4);
    } > FLASH

    .bss STACK_POINTER (NOLOAD) :
    {
        BSS_START = .;
        *(.sbss);
        *(.bss.*);
        *(COMMON);
        . = ALIGN(4);
        BSS_END = .;
    } > RAM

    .data ADDR(.bss) + SIZEOF(.bss) :
    {
        DATA_LOAD = LOADADDR(.data);
        DATA_START = .;
        *(.data.*);
    } > RAM AT > FLASH

    .dronereg ADDR(.data) + SIZEOF(.data) (NOLOAD) :
    {
        *(.dronereg.DSO_PORTS);
        . = ALIGN(4);
        DATA_END = .;
    } > RAM

    .heap ADDR(.dronereg) + SIZEOF(.dronereg) (NOLOAD) :
    {
        HEAP_START = .;
        . += {{size config.heap.main.size}};
        . = ALIGN(4);
        HEAP_END = .;
    } > RAM

    /DISCARD/ :
    {
{{~ #if (eq config.linker.platform "arm") }}
        *(.ARM.*)
{{~ /if}}{{#if (eq config.linker.platform "riscv") }}
        *(.eh_frame .eh_frame_hdr)
{{~ /if}}
    }
}

{{~ #each config.linker.include}}
INCLUDE {{this}};
{{~ /each}}
